/*
	The MIT License

	Copyright (c) 2008 IFMO/GameDev Studio

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/
// d3d_render_system.h - 


#pragma once


struct  vidState_s	{
		int		fullscr;
		int		mode;
		HWND	h_wnd;
	};


class ED3DImage : public IImage {
	public:
						ED3DImage	( const char *path );
		virtual			~ED3DImage	( void );
		virtual	uint	GetWidth	( void ) const { return width; }
		virtual	uint	GetHeight	( void ) const { return height; }

		virtual void	BeginWrite	( void );
		virtual void	WritePixel	( int x, int y, uint color );
		virtual void	EndWrite	( void );

		virtual void	FilterRT	( void );
		
		const char		*Name		( void ) const { return name.c_str(); }
		const LPDIRECT3DBASETEXTURE9 Texture ( void ) const { return d3d_tex; }
		LPDIRECT3DSURFACE9			 Surface ( void ) { return d3d_surf; }

	protected:
		void			CreateImageFromFile		( const char *path );
		void			CreateNULLImage			( const char *path );
		void			CreateSolidImage		( const char *path, uchar r, uchar g, uchar b, uchar a );
		void			CreateRenderTarget		( const char *path, uint w, uint h );
		void			CreatePlaybackTexture	( const char *path );

		D3DLOCKED_RECT write_rect;
		
		LPDIRECT3DBASETEXTURE9	d3d_tex;
		LPDIRECT3DSURFACE9		d3d_surf;
		string	name;
		uint	width;
		uint	height;
	};



class ED3DRenderSystem : public IRenderSystem {
	public:
							ED3DRenderSystem	( const ap_t &ap );
		virtual 			~ED3DRenderSystem	( void );

		virtual void		BeginFrame			( void );		
		virtual	void		RenderFrame			( void );
		virtual void		EndFrame			( void );

		//	Resource stuff :
		virtual	void		BeginRegistration	( const char *mapname );
		virtual	IImage		*RegisterImage		( const char *name );
		virtual void		EndRegistration		( void );
		
		//	Misc stuff :
		virtual void		GetScreenSize		( uint &w, uint &h );
		virtual void		*GetWndDescriptor	( void );
		
		virtual void		SetRenderTarget		( IImage *render_target );
		virtual void		ClearRenderTarget	( void );
		virtual void		SetWriteMask		( bool rgb, bool a );

		virtual	uint		GetModeNum			( void );
		virtual void		GetModeWH			( uint n, uint &w, uint &h );
		virtual bool		IsModeSupported		( uint n );
		virtual	uint		GetCurrentMode		( void );
		
		//	UI support :
		virtual void		SetTextureAddrMode	( uint sampler, uint addr_mode );
		virtual void		SetTransform		( const EMatrix4 &matrix );
		virtual void		SetProjection		( const EMatrix4 &matrix );
		virtual void		Set2DColor			( const EVec4 &color );
		virtual void		SetViewport			( int x, int y, int w, int h );
		virtual void		Set2DViewMode		( float offset_x=0, float offset_y=0 );
		virtual void		Set2DBlendMode		( ERSBlendMode_t mode );
		virtual void		SetCustom2DViewMode	( const EVec2 &upper_left, const EVec2 &lower_right );
		virtual void		DrawImage			( float x, float y, const char *name, const EVec4 color );
		virtual void		DrawRectOutline		( float x, float y, float w, float h, const EVec4 &color );
		virtual void		DrawStretchImage	( float x, float y, float w, float h, const char *name, const EVec4 color );

		virtual void		DrawPolygon			( uint vert_num, const vert2d_s *vert_list, const char *tex_name );
		virtual void		DrawQuadList		( uint quad_num, const quad_s *quad_list, const char *tex_name );

	public:
		LPDIRECT3DDEVICE9	GetD3DDevice		( void ) { return d3ddev; }
		void				ResetDeviceState	( void );
		void				DrawQuad			( float x0, float y0, float x1, float y1, 
												  float u0, float v0, float u1, float v1, uint32_t color4b );
		void                DrawQuadNoTex       ( float x0, float y0, float x1, float y1, uint32_t color4b );
												  
		void				SetSampler			( uint stage, const IImage *image );
		
		class ECudaTest		*cuda_test;
		class ECudaTestMRI	*cuda_test_mri;
		
	protected:
		LPDIRECT3DSURFACE9 default_color_surf;
		LPDIRECT3DSURFACE9 default_depth_surf;

	public:
		ap_t	ap;
		LPDIRECT3D9			d3d;
		LPDIRECT3DDEVICE9	d3ddev;
		
		EVec4	color_2d_multiplier;

		//
		//	Init/shutdown stuff :
		//
		void			CheckDisplayModes	( void );
		void			InitDisplay			( void );
		void			InitDirect3D		( void );
		void			ShutdownDisplay		( void );
		void			ShutdownDirect3D	( void );
		void			ScreenShot			( void );
		
		static void		ListDisplayModes_f	( ED3DRenderSystem *self, int argc, char **argv );
		static void		ScreenShot_f		( ED3DRenderSystem *self, int argc, char **argv );
		static LRESULT	WndProc				( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
		bool			need_screenshot;
		
		vidState_s	vid_state;		
		IVar		*d3d_mode;
		IVar		*d3d_fullscr;
		IVar		*d3d_xpos, *d3d_ypos;
		
		//
		//	Resource stuff :
		//
		void		ReleaseImages	( void );
		vector<ED3DImage*>	image_list;
		
	};
	
	
	
	
	
	
	
	
	
	